package com.ruoyi.fire.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.ResponseEntityInfo;
import com.ruoyi.common.enums.PushStatus;
import com.ruoyi.common.enums.RequestMapper;
import com.ruoyi.common.enums.UnitType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.*;
import com.ruoyi.fire.domain.TDevice;
import com.ruoyi.fire.domain.TFloor;
import com.ruoyi.fire.domain.TUnit;
import com.ruoyi.fire.service.ITUnitService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.fire.mapper.TBuildingMapper;
import com.ruoyi.fire.domain.TBuilding;
import com.ruoyi.fire.service.ITBuildingService;
import org.springframework.util.CollectionUtils;

/**
 * 建筑物Service业务层处理
 *
 * @author ruoyi
 * @date 2025-11-02
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TBuildingServiceImpl extends ServiceImpl<TBuildingMapper, TBuilding> implements ITBuildingService {
    @Autowired
    private TBuildingMapper tBuildingMapper;

    private final ITUnitService unitService;
    private final RequestService requestService;
    // 添加线程池注入
    private final Executor threadPoolTaskExecutor;

    /**
     * 查询建筑物
     *
     * @param id 建筑物主键
     * @return 建筑物
     */
    @Override
    public TBuilding selectTBuildingById(String id) {
        return tBuildingMapper.selectTBuildingById(id);
    }

    /**
     * 查询建筑物列表
     *
     * @param tBuilding 建筑物
     * @return 建筑物
     */
    @Override
    public List<TBuilding> selectTBuildingList(TBuilding tBuilding) {
        List<TBuilding> tBuildings = tBuildingMapper.selectTBuildingList(tBuilding);
        if (!CollectionUtils.isEmpty(tBuildings)) {
            for (TBuilding building : tBuildings) {
                building.setUnit(unitService.getById(building.getUnitId()));
            }
        }
        return tBuildings;
    }

    /**
     * 新增建筑物
     *
     * @param tBuilding 建筑物
     * @return 结果
     */
    @Override
    public boolean insertTBuilding(TBuilding tBuilding) {

        TUnit tUnit = unitService.getById(tBuilding.getUnitId());

        boolean isNetworkedUnit = UnitType.NETWORKED_UNITS.getCode().equals(tUnit.getUnitType());

        if (isNetworkedUnit) {
            tBuilding.setPushStatus(PushStatus.PUSH_FAILED.getCode());
        } else {
            tBuilding.setPushStatus(PushStatus.NOT_PUSHED.getCode());
        }

        Long userId = SecurityUtils.getUserId();
        String username = SecurityUtils.getUsername();
        tBuilding.setCreateBy(username);
        tBuilding.setCreateTime(DateUtils.getNowDate());
        tBuilding.setCreateUserId(userId);

        boolean result = save(tBuilding);
        if (result && isNetworkedUnit) {
            // 提交至线程池异步处理推送逻辑
            threadPoolTaskExecutor.execute(() -> {
                try {
                    Map<String, Object> unitMap = ConvertToMap.convertObjectToMap(tBuilding);
                    unitMap.remove("id");
                    unitMap.put("unit_id", tUnit.getUnitId());
                    ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(RequestMapper.ADD_BUILDING, unitMap);

                    TBuilding building = JSON.parseObject(responseEntityInfo.getData().toString(), TBuilding.class);

                    LambdaUpdateWrapper<TBuilding> updateWrapper = Wrappers.lambdaUpdate(TBuilding.class)
                            .eq(TBuilding::getId, tBuilding.getId())
                            .set(TBuilding::getPushStatus, PushStatus.PUSH_SUCCESSFUL.getCode())
                            .set(TBuilding::getBuildingId, building.getId());
                    update(updateWrapper);
                } catch (Exception e) {
                    log.error("推送建筑物失败: id={}, error={}", tBuilding.getId(), e.getMessage(), e);

                    // 更新推送状态为失败
                    LambdaUpdateWrapper<TBuilding> failUpdateWrapper = Wrappers.lambdaUpdate(TBuilding.class)
                            .eq(TBuilding::getId, tBuilding.getId())
                            .set(TBuilding::getPushStatus, PushStatus.PUSH_FAILED.getCode());
                    update(failUpdateWrapper);
                }
            });
        }
        return result;
    }

    /**
     * 修改建筑物
     *
     * @param tBuilding 建筑物
     * @return 结果
     */
    @Override
    public int updateTBuilding(TBuilding tBuilding) {

        TUnit tUnit = unitService.getById(tBuilding.getUnitId());

        boolean isNetworkedUnit = UnitType.NETWORKED_UNITS.getCode().equals(tUnit.getUnitType());

        // 设置推送状态
        if (!isNetworkedUnit) {
            tBuilding.setPushStatus(PushStatus.NOT_PUSHED.getCode());
        }

        tBuilding.setUpdateTime(DateUtils.getNowDate());
        int result = tBuildingMapper.updateTBuilding(tBuilding);

        if (result > 0 && isNetworkedUnit) {
            // 提交至线程池异步处理推送逻辑
            threadPoolTaskExecutor.execute(() -> {
                try {

                    RequestMapper requestMapper = tBuilding.getBuildingId() != null ? RequestMapper.UPDATE_BUILDING : RequestMapper.ADD_BUILDING;
                    Map<String, Object> buildingMap = ConvertToMap.convertObjectToMap(tBuilding);
                    if (tBuilding.getBuildingId() != null) {
                        buildingMap.put("id", tBuilding.getBuildingId());
                    } else {
                        buildingMap.remove("id");
                    }
                    ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(requestMapper, buildingMap);

                    TBuilding building = JSON.parseObject(responseEntityInfo.getData().toString(), TBuilding.class);

                    LambdaUpdateWrapper<TBuilding> updateWrapper = Wrappers.lambdaUpdate(TBuilding.class)
                            .eq(TBuilding::getId, tBuilding.getId())
                            .set(TBuilding::getPushStatus, PushStatus.PUSH_SUCCESSFUL.getCode())
                            .set(TBuilding::getBuildingId, building.getId());
                    update(updateWrapper);
                } catch (Exception e) {
                    log.error("推送建筑物失败: buildingId={}, error={}", tBuilding.getId(), e.getMessage(), e);

                    // 更新推送状态为失败
                    LambdaUpdateWrapper<TBuilding> failUpdateWrapper = Wrappers.lambdaUpdate(TBuilding.class)
                            .eq(TBuilding::getId, tBuilding.getId())
                            .set(TBuilding::getPushStatus, PushStatus.PUSH_FAILED.getCode());
                    update(failUpdateWrapper);
                }
            });
        }
        return result;
    }

    /**
     * 批量删除建筑物
     *
     * @param ids 需要删除的建筑物主键
     * @return 结果
     */
    @Override
    public int deleteTBuildingByIds(String[] ids) {
        return tBuildingMapper.deleteTBuildingByIds(ids);
    }

    /**
     * 删除建筑物信息
     *
     * @param id 建筑物主键
     * @return 结果
     */
    @Override
    public int deleteTBuildingById(String id) {
        return tBuildingMapper.deleteTBuildingById(id);
    }

    /**
     * 同步单位信息
     *
     * @param id 单位信息主键
     * @return 结果
     */
    @Override
    public boolean pushTUnit(String id) {
        TBuilding building = getById(id);
        if (building == null) {
            log.warn("建筑物信息不存在，id={}", id);
            return false;
        }

        boolean isNew = building.getBuildingId() == null || building.getBuildingId().equals("");

        doPush(isNew, building);
        return true;
    }

    /**
     * 远程删除建筑物
     *
     * @param buildingId 建筑物信息主键
     * @return 删除结果
     */
    @Override
    public boolean remoteDeletion(String buildingId) {
        TBuilding building = getById(buildingId);
        if (StringUtils.isNotNull(building)) {
            Map<String, Object> params = new HashMap<>();
            params.put("id", building.getBuildingId());
            ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(RequestMapper.BUILDING_DELETE, params);

            if (responseEntityInfo.getErrno() == 0) {
                LambdaUpdateWrapper<TBuilding> updateWrapper = Wrappers.lambdaUpdate(TBuilding.class);
                updateWrapper.set(TBuilding::getBuildingId, "");
                updateWrapper.set(TBuilding::getPushStatus, PushStatus.NOT_PUSHED.getCode());
                updateWrapper.eq(TBuilding::getId, building.getId());
                update(updateWrapper);
            }
            throw new ServiceException("远程删除失败： " + responseEntityInfo.getErrmsg());
        }
        return true;
    }

    /**
     * 先删除远程在删除本地信息
     *
     * @param buildingId 建筑物信息主键
     * @return 删除结果
     */
    @Override
    public int removeByBuildingId(String buildingId) {
        TBuilding building = getById(buildingId);
        if (StringUtils.isNotNull(building) && StringUtils.isNotEmpty(building.getBuildingId())) {
            Map<String, Object> params = new HashMap<>();
            params.put("id", building.getBuildingId());
            ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(RequestMapper.BUILDING_DELETE, params);

            if (responseEntityInfo.getErrno() == 0) {
                removeById(buildingId);
            } else {
                throw new ServiceException("远程删除失败： " + responseEntityInfo.getErrmsg());
            }
        }
        return 0;
    }

    private void doPush(boolean isNew, TBuilding building) {
        String requestType = isNew ? "新增建筑物信息" : "修改建筑物信息";
        log.info("开始{}推送，unitId={}", requestType, building.getId());

        Map<String, Object> unitMap = ConvertToMap.convertObjectToMap(building);
        if (isNew) {
            TUnit unit = unitService.getById(building.getUnitId());
            unitMap.remove("id");
            unitMap.put("unit_id", unit.getUnitId());
        } else {
            unitMap.put("id", building.getBuildingId());
        }

        RequestMapper mapper = isNew ? RequestMapper.ADD_BUILDING : RequestMapper.UPDATE_BUILDING;
        ResponseEntityInfo responseEntityInfo = requestService.advancedRequest(mapper, unitMap);

        if (responseEntityInfo.getErrno() != 0) {
            log.error("{}推送失败，unitId={}, error={}", requestType, building.getId(), responseEntityInfo.getErrmsg());

            // 推送失败
            LambdaUpdateWrapper<TBuilding> failUpdateWrapper = Wrappers.lambdaUpdate(TBuilding.class)
                    .eq(TBuilding::getId, building.getId())
                    .set(TBuilding::getPushStatus, PushStatus.PUSH_FAILED.getCode());

            update(failUpdateWrapper);
            throw new ServiceException(responseEntityInfo.getErrmsg());
        }

        TBuilding buildingResult = JSON.parseObject(responseEntityInfo.getData().toString(), TBuilding.class);

        LambdaUpdateWrapper<TBuilding> updateWrapper = Wrappers.lambdaUpdate(TBuilding.class)
                .eq(TBuilding::getId, building.getId())
                .set(TBuilding::getPushStatus, PushStatus.PUSH_SUCCESSFUL.getCode())
                .set(TBuilding::getBuildingId, buildingResult.getId());

        update(updateWrapper);

        log.info("{}推送成功，unitId={}", requestType, building.getId());
    }
}
